package com.lixian.mypro;

import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.util.Log;

import java.io.IOException;
import java.nio.ByteBuffer;

/**
 * Created by Administrator on 2018/3/1.
 */

public class MixTask implements Runnable {
    private String videoPath;
    private String audioPath;

    public MixTask(String audioPath, MixStateCallBack call, String outPutFilePath, String videoPath) {
        this.audioPath = audioPath;
        this.call = call;
        this.outPutFilePath = outPutFilePath;
        this.videoPath = videoPath;
    }

    private String outPutFilePath;
    private MixStateCallBack call;
    @Override
    public void run() {
        call.onmixStart();
        MediaExtractor videoExtractor = new MediaExtractor();
        MediaExtractor audioExtractor = new MediaExtractor();
        try {
            //设置数据源
            videoExtractor.setDataSource(videoPath);
            MediaMuxer muxer=new MediaMuxer(outPutFilePath,MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
            audioExtractor.setDataSource(audioPath);
            //找信道
            int audioTrack=-1;
            int videoTrack=-1;
            int sourceaudioTrack=-1;
            int sourcevideoTrack=-1;
            for (int i = 0; i < audioExtractor.getTrackCount(); i++) {
                MediaFormat format = audioExtractor.getTrackFormat(i);
                String formatString = format.getString(MediaFormat.KEY_MIME);
                if (formatString.equals(MediaFormat.MIMETYPE_AUDIO_AAC)) {
                    //MediaMuxer 支持这个格式的音频
                    sourceaudioTrack=i;
                    audioTrack=muxer.addTrack(format);
                    Log.e("MixThread","音频格式"+formatString);
                    break;
                }
            }
            for (int i = 0; i < videoExtractor.getTrackCount(); i++) {
                MediaFormat format = videoExtractor.getTrackFormat(i);
                if (format.getString(MediaFormat.KEY_MIME).startsWith("video/")) {
                    videoTrack=muxer.addTrack(format);
                    sourcevideoTrack=i;
                    Log.e("MixThread","视频信道"+i);
                    break;
                }
            }
            if (sourceaudioTrack==-1) {
                call.onError(new NullPointerException("音频文件无效"));
                return;
            }
            if (sourcevideoTrack==-1) {
                call.onError(new NullPointerException("视频文件无效"));
                return;
            }
            videoExtractor.selectTrack(sourcevideoTrack);
            ByteBuffer videoBuffer=ByteBuffer.allocate(500*1024);

            videoExtractor.readSampleData(videoBuffer, 0);
            if (videoExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC) {
                videoExtractor.advance();
            }
            videoExtractor.readSampleData(videoBuffer, 0);
            long secondTime = videoExtractor.getSampleTime();
            videoExtractor.advance();
            long thirdTime = videoExtractor.getSampleTime();
            long videoTime= Math.abs(thirdTime - secondTime);

            videoExtractor.unselectTrack(sourcevideoTrack);
            videoExtractor.selectTrack(sourcevideoTrack);
            muxer.start();
            MediaCodec.BufferInfo videoInfo=new MediaCodec.BufferInfo();
            int frameCount=0;
            while(true){
                int i = videoExtractor.readSampleData(videoBuffer, 0);
                if (i<0) {
                    break;
                }
                videoInfo.offset=0;
                videoInfo.flags=videoExtractor.getSampleFlags();
                videoInfo.presentationTimeUs+=videoTime;
                videoInfo.size=i;
                muxer.writeSampleData(videoTrack,videoBuffer,videoInfo);
                videoExtractor.advance();
                videoBuffer.clear();
                frameCount++;
                call.onProgress();
                Log.e("MixThread","视频正在写入");
            }
            Log.e("MixThread","视频写入完成");
            audioExtractor.selectTrack(sourceaudioTrack);
            MediaCodec.BufferInfo audioInfo = new MediaCodec.BufferInfo();
            ByteBuffer audioBuffer = ByteBuffer.allocate(500 * 1024);
            for (int i = 0; i < frameCount; i++) {
                int j = audioExtractor.readSampleData(audioBuffer, 0);
                if(j<0){
                    audioExtractor.unselectTrack(sourceaudioTrack);
                    audioExtractor.selectTrack(sourceaudioTrack);
                    j=audioExtractor.readSampleData(audioBuffer,0);
                }
                audioInfo.size=j;
                audioInfo.flags=audioExtractor.getSampleFlags();
                audioInfo.presentationTimeUs+=videoTime;
                audioInfo.offset=0;
                muxer.writeSampleData(audioTrack,audioBuffer,audioInfo);
                audioExtractor.advance();
                call.onProgress();
            }
            Log.e("MixThread","音频写入完成,合成完毕");
            muxer.stop();
            muxer.release();
            audioExtractor.release();
            videoExtractor.release();
            audioBuffer.clear();
            videoBuffer.clear();
            audioBuffer=null;
            audioInfo=null;
            videoBuffer=null;
            videoInfo=null;
            call.onSuccess();
        } catch (IOException e) {
            call.onError(e);
        }
    }

}

